In [1]:
from IPython.display import YouTubeVideo
In [2]:
YouTubeVideo("xAoljeRJ3lU")
Out[2]:
First, import numpy and matplotlib libraries (don't forget the matplotlib inline magic command).
In [3]:
# Your code
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
Let's do the experiment. The procedure is as follows:
First, we use two lists to store perceived and actual length.
In [4]:
import random
import time
n1 = 0.01
length_perceived = []
length_actual = []
Let's run the experiment.
The random module in Python provides various random number generators, and the random.uniform(a,b) function returns a float in [a,b].
We can plot horizontal bars using the pyplot.barh() function. The lengths of them are 0.01, n2, 0.1. Using this function, produce a bar graph that looks like this:
In [20]:
plt.gca().set_frame_on(True)
plt.gca().get_xaxis().set_visible(False)
plt.yticks(np.arange(3)+0.25, ('1', '?', '10'))
# TODO: generate a random number in [0.01, 0.1) using random.uniform(a,b) function and n1
# Your code
# n2 = ...
# Your code
# plt.barh(np.arange(3), ... )
n2 = random.uniform(n1,0.1)
plt.barh(np.arange(3), [n1, n2, 0.1])
Out[20]:
From the plot above, guess the ratio between the length of the middle and the bottom bar. We can think of this more directly: If the length of the bottom bar is 1 and the top one is 10, what is the length of the middle one?
Put your guess (perceived length) in length_perceived.append(). And the length_actual.append(n2/n1) will store the actual ratio.
In [21]:
length_actual.append(n2/n1)
# put the ratio that you guessed and run this cell. replace "3" with your guess and press shift + enter.
length_perceived.append(1.5)
print (length_actual)
print (length_perceived)
Run the above two cells many times, namely: (1) generate a random bar graph, (2) put your guess into length_perceived while entering the actuall ratio into length_actual
Now we can draw the scatter plot of perceived and actual length. The scatter() function will do this. Here is an example of how to use scatter:
In [13]:
plt.scatter([1,5,10], [1,10, 5])
Out[13]:
In [22]:
# Your code
# plt.scatter(...)
plt.scatter(length_actual,length_perceived)
# Don't forget to label the axes!
plt.title("Is Steven's power law true? (Length)")
plt.xlabel("Actual")
plt.ylabel("Perceived")
Out[22]:
After plotting, let's fit the relation between actual and perceived lengths using a polynomial function. We can easily do it using curve_fit(f, x, y) in Scipy, which is to fit $x$ and $y$ using the function f. In our case, $f = a*x^b +c$. For instance, we can check whether this works by creating a fake dataset that follows the exact form:
In [23]:
from scipy.optimize import curve_fit
def func(x, a, b, c):
return a * np.power(x, b) + c
x = np.arange(20) # [0,1,2,3, ..., 19]
y = np.power(x, 2) # [0,1,4,9, ... ]
popt, pcov = curve_fit(func, x, y)
print('{:.2f} x^{:.2f} + {:.2f}'.format(*popt))
Now you can fit your data.
In [24]:
# Your code
# ... = curve_fit(... )
popt, pcov = curve_fit(func, length_actual, length_perceived)
print('{:.2f} x^{:.2f} + {:.2f}'.format(*popt))
Similar to the above experiment, we now represent a random number as a circle, and the area of the circle is equal to the number.
First, calculate the radius of a circle from its area and then plot using the Circle() function. plt.Circle((0,0), r) will plot a circle centered at (0,0) with radius r.
In [25]:
import math
radius1 = math.sqrt(n1/math.pi) # area = pi * r * r
radius2 = math.sqrt(n2/math.pi)
plt.axis('equal')
plt.axis('off')
circ1 = plt.Circle( (0,0), radius1, clip_on=False )
circ2 = plt.Circle( (4*radius2,0), radius2, clip_on=False )
plt.gca().add_artist(circ1)
plt.gca().add_artist(circ2)
Out[25]:
Write the code to run the experiment in a similar way, plot and fit your results in the cell below. (Feel free to create multiple cells below)
In [34]:
area_percieved = []
area_actual = []
In [41]:
import math
n1 = 0.01
n2 = random.uniform(n1, 0.1)
radius1 = math.sqrt(n1/math.pi) # area = pi * r * r
radius2 = math.sqrt(n2/math.pi)
plt.axis('equal')
plt.axis('off')
circ1 = plt.Circle( (0,0), radius1, clip_on=False )
circ2 = plt.Circle( (4*radius2,0), radius2, clip_on=False )
plt.gca().add_artist(circ1)
plt.gca().add_artist(circ2)
area_actual.append(n2/n1)
Show the scatter plot and the curve fit. Does it follow Stevens' power-law?
In [42]:
# Your code
area_percieved.append(5)
print (area_actual)
print (area_percieved)
In [43]:
plt.scatter(area_actual, area_percieved)
# Don't forget to label the axes!
plt.title("Is Steven's power law true? (Area)")
plt.xlabel("Actual")
plt.ylabel("Perceived")
Out[43]:
In [44]:
popt, pcov = curve_fit(func, area_actual, area_percieved)
print('{:.2f} x^{:.2f} + {:.2f}'.format(*popt))
In [45]:
x = np.linspace(0, 3*np.pi)
plt.plot(x, np.sin(x), color='r', lw=3)
plt.plot(x, np.sin(x-np.pi), color='g', lw=3)
Out[45]:
We can also use different color schemes in matplotlib. Here you can find them
In [46]:
plt.plot(x, np.sin(x), color=plt.cm.Accent(0), lw=3)
plt.plot(x, np.sin(x-np.pi), color=plt.cm.Accent(1.0), lw=3)
Out[46]:
In [47]:
num_lines = 5
x = np.linspace(0, 4*np.pi)
shift = np.linspace(0, np.pi, num_lines)
color_idx = np.linspace(0, 1, num_lines)
for i in range(len(color_idx)):
plt.plot(x, np.sin(x - shift[i]), color=plt.cm.Accent(color_idx[i]), lw=3)
Pick two color schemes from
In [48]:
# Your code
num_lines = 5
x = np.linspace(0, 4*np.pi)
shift = np.linspace(0, np.pi, num_lines)
color_idx = np.linspace(0, 1, num_lines)
for i in range(len(color_idx)):
plt.plot(x, np.sin(x - shift[i]), color=plt.cm.Pastel1(color_idx[i]), lw=3)
In [49]:
num_lines = 5
x = np.linspace(0, 4*np.pi)
shift = np.linspace(0, np.pi, num_lines)
color_idx = np.linspace(0, 1, num_lines)
for i in range(len(color_idx)):
plt.plot(x, np.sin(x - shift[i]), color=plt.cm.Set1(color_idx[i]), lw=3)
These are essentially based on matplotlib, but Seaborn makes pre-defined, good-looking palettes that you can use.
See: https://stanford.edu/~mwaskom/software/seaborn/generated/seaborn.color_palette.html#seaborn.color_palette https://stanford.edu/~mwaskom/software/seaborn/tutorial/color_palettes.html
In [50]:
import seaborn as sns
In [51]:
sns.set(style="white")
# Load the example planets dataset
planets = sns.load_dataset("planets")
years = np.arange(2000, 2015)
#Make a barplot with default color
g = sns.factorplot(x="year", data=planets, kind="count", size=4, aspect=1.5, order=years)
To specify a palette:
In [52]:
g = sns.factorplot(x="year", data=planets, kind="count", size=4, aspect=1.5, order=years, palette="muted")
We can also create a palette, and pass it as an argument:
In [53]:
p = sns.cubehelix_palette(15)
g = sns.factorplot(x="year", data=planets, kind="count", size=4, aspect=1.5, order=years, palette=p)
http://matplotlib.org/users/image_tutorial.html
We can also display an image using Colormaps. First read it using the imread() function that returns an numpy.array().
In [54]:
import matplotlib.image as mpimg
In [55]:
img = mpimg.imread('sneakySnake.png')
In [56]:
plt.imshow(img)
Out[56]:
How does img store the image? Run the following cells
In [57]:
img
Out[57]:
In [58]:
np.shape(img)
Out[58]:
This means that img is a three-dimensional array with 219 x 329 x 4 numbers. If you look at the image, you can easily see that 219 and 329 are the dimensions (height and width in terms of the number of pixels) of the image. What is 4?
We can actually create our own small image to investigate. Let's create a 3x3 image.
In [59]:
myimg = np.array([ [[1,0,0,1], [1,1,1,1], [1,1,1,1]],
[[1,1,1,1], [1,1,1,1], [1,0,0,1]],
[[1,1,1,1], [1,1,1,1], [1,0,1,0.5]] ])
plt.imshow(myimg)
Out[59]:
Why are they blurred? It should have only 3 pixels across, right? It's because of interpolation. By setting it to nearest you can get the raw pixel values more clearly.
In [60]:
plt.imshow(myimg, interpolation="nearest")
Out[60]:
Play with the values of the matrix, and explain what are each of the four dimensions (this matrix is 3x3x4) below.
YOUR ANSWER HERE
It represent RGBA(Red-Green-Blue-Alpha Channel) values of that particular pixel.Generally the alpha represents the opacity of the associated pixel.
For example 0.8, 0.4, 0.9, 1 represents values associated with Red, Green, Blue and the alpha.
Let's assume that the first value of the four dimensions represents some data of your interest. You can obtain height x width x 1 matrix by doing img[:,:,0], which means give me the all of the first dimension (:), all of the second dimension (:), but only the first one from the last dimension (0).
In [61]:
plt.pcolormesh(img[:,:,0], cmap=plt.cm.viridis)
plt.colorbar()
Out[61]:
Why is it flipped upside down? Take a look at the previous imshow example closely and compare the axes across these two displays. Below, flip the figure upside down to show it properly. This function numpy.flipud() should be handy.
In [62]:
# your code
plt.pcolormesh(np.flipud(img[:,:,0]), cmap=plt.cm.viridis)
plt.colorbar()
Out[62]:
In [ ]: